﻿namespace DimensionsHelper.LanguageService.Syntax;

public abstract class ModifiedSignatureWithParameters : SignatureWithParameters
{
    private SyntaxList<SyntaxToken>? _modifiers;

    protected internal ModifiedSignatureWithParameters(SyntaxKinds kind, SyntaxToken declareKeywordToken,
        Identifier name, SyntaxNode? parent) :
        base(kind, declareKeywordToken, name, parent)
    {
    }

    /// <summary>
    ///     获取修饰符列表
    /// </summary>
    public IReadOnlyList<SyntaxToken> Modifiers =>
        _modifiers == null ? new List<SyntaxToken>() : _modifiers;


    /// <summary>
    ///     是否带有 ReadOnly 关键字
    /// </summary>
    public bool IsReadOnly { get; protected set; }


    /// <summary>
    ///     是否带有 WriteOnly 关键字
    /// </summary>
    public bool IsWriteOnly { get; protected set; }


    /// <summary>
    ///     是否带有 Default 关键字
    /// </summary>
    public bool IsDefault { get; protected set; }


    /// <summary>
    ///     是否带有 Nullable 修饰符
    /// </summary>
    public bool IsNullable { get; protected set; }


    /// <summary>
    ///     如果包含了修饰关键字，返回<see langword="true" />
    /// </summary>
    public bool IsModified => _modifiers is { Count: > 0 };


    protected virtual bool VerifyModifierToken(SyntaxToken token)
    {
        return true;
    }


    /// <summary>
    ///     添加一个新的修饰关键字，如果修饰符无效或者重复，返回<see langword="false" />
    /// </summary>
    public bool TryAddModifier(SyntaxToken token)
    {
        if (!VerifyModifierToken(token))
        {
            return false;
        }

        AddChildMember(ref _modifiers, token);
        return true;
    }


    public override bool ContainsModifier(SyntaxKinds kind)
    {
        return _modifiers != null && _modifiers.Any(e => e.IsNode(kind));
    }


    public override bool ContainsAnyModifier(params SyntaxKinds[] modifiersKinds)
    {
        return _modifiers != null && _modifiers.Any(e => e.IsOneOfNode(modifiersKinds));
    }


    public override void AcceptVisitor<T>(SyntaxNodeVisitor<T> visitor)
    {
        AcceptList(visitor, Modifiers);
        Accept(visitor, DeclareKeywordToken, NameIdentifier);
        AcceptList(visitor, Parameters);
        Accept(visitor, Binding);
    }
}